<template>
	<a-select
		v-if="async"
		showSearch
		labelInValue
		:disabled="disabled"
		:getPopupContainer="(node) => node.parentNode"
		@search="loadData"
		:placeholder="placeholder"
		v-model="selectedAsyncValue"
		style="width: 100%"
		:filterOption="false"
		@change="handleAsyncChange"
		allowClear
		:notFoundContent="loading ? undefined : null"
	>
		<a-spin v-if="loading" slot="notFoundContent" size="small" />
		<a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
	</a-select>

	<a-select
		v-else
		:getPopupContainer="(node) => node.parentNode"
		showSearch
		:disabled="disabled"
		:placeholder="placeholder"
		optionFilterProp="children"
		style="width: 100%"
		@change="handleChange"
		:filterOption="filterOption"
		v-model="selectedValue"
		allowClear
		:notFoundContent="loading ? undefined : null"
	>
		<a-spin v-if="loading" slot="notFoundContent" size="small" />
		<a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
	</a-select>
</template>

<script>
import {  getDictItemsFromCache } from '@/services/common';
import debounce from 'lodash/debounce';

export default {
	name: 'TSearchSelectTag',
	props: {
		disabled: Boolean,
		value: [String, Number],
		dict: String,
		dictOptions: Array,
		async: Boolean,
		placeholder: {
			type: String,
			default: '请选择',
			required: false,
		},
	},
	data() {
		this.loadData = debounce(this.loadData, 800); //消抖
		this.lastLoad = 0;
		return {
			loading: false,
			selectedValue: [],
			selectedAsyncValue: [],
			options: [],
		};
	},
	created() {
		this.initDictData();
	},
	watch: {
		value: {
			immediate: true,
			handler(val) {
				if (!val) {
					if (val == 0) {
						this.initSelectValue();
					} else {
						this.selectedValue = [];
						this.selectedAsyncValue = [];
					}
				} else {
					this.initSelectValue();
				}
			},
		},
		dict: {
			handler() {
				this.initDictData();
			},
		},
	},
	methods: {
		initSelectValue() {
			if (this.async) {
				if (
					!this.selectedAsyncValue ||
					!this.selectedAsyncValue.key ||
					this.selectedAsyncValue.key != this.value
				) {
					this.$post(`/system/dicSet/getDicItemByCode`, { code: this.value }).then((res) => {
						if (res.statusCode != 300) {
							let obj = {
								key: this.value,
								label: res.result,
							};
							this.selectedAsyncValue = { ...obj };
						}
					});
				}
			} else {
				this.selectedValue = this.value.toString();
			}
		},
		loadData(value) {
			this.lastLoad += 1;
			const currentLoad = this.lastLoad;
			this.options = [];
			this.loading = true;
			// 字典code格式：table,text,code
			this.$post(`/system/dicSet/getDicItemByCode`, { code: value }).then((res) => {
				this.loading = false;
				if (res.statusCode !== 300) {
					if (currentLoad != this.lastLoad) {
						return;
					}
					this.options = res;
				} else {
					this.$message.warning(res.message);
				}
			});
		},
		initDictData() {
			if (!this.async) {
				//如果字典项集合有数据
				if (this.dictOptions && this.dictOptions.length > 0) {
					this.options = [...this.dictOptions];
				} else {
					//根据字典Code, 初始化字典数组
					let dictStr = '';
					if (this.dict) {
						let arr = this.dict.split(',');
						if (arr[0].indexOf('where') > 0) {
							let tbInfo = arr[0].split('where');
							dictStr =
								tbInfo[0].trim() + ',' + arr[1] + ',' + arr[2] + ',' + encodeURIComponent(tbInfo[1]);
						} else {
							dictStr = this.dict;
						}
						if (this.dict.indexOf(',') == -1) {
							//优先从缓存中读取字典配置
							if (getDictItemsFromCache(this.dictCode)) {
								this.options = getDictItemsFromCache(this.dictCode);
								return;
							}
						}
						this.$post('/system/dicSet/getDicItemByCode', { code: dictStr }, null).then((res) => {
							if (res.statusCode != 300) {
								this.options = res.result;
							}
						});
					}
				}
			}
		},
		filterOption(input, option) {
			return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0;
		},
		handleChange(selectedValue) {
			this.selectedValue = selectedValue;
			this.callback();
		},
		handleAsyncChange(selectedObj) {
			this.selectedAsyncValue = selectedObj;
			this.selectedValue = selectedObj.key;
			this.callback();
		},
		callback() {
			this.$emit('change', this.selectedValue);
		},
		setCurrentDictOptions(dictOptions) {
			this.options = dictOptions;
		},
		getCurrentDictOptions() {
			return this.options;
		},
	},
	model: {
		prop: 'value',
		event: 'change',
	},
};
</script>

<style scoped></style>
